package rexsee.ebook;

import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Set;

import rexsee.core.application.RexseeApplication;
import rexsee.core.browser.Browser;
import rexsee.core.browser.RexseePregFilter;
import rexsee.core.browser.clazz.JavascriptInterface;
import rexsee.core.browser.clazz.PregFilterListener;
import rexsee.core.browser.clazz.PregPair;
import android.app.Activity;
import android.content.Context;
import android.content.DialogInterface;

public class RexseePageFlip implements JavascriptInterface {

	public static final String INTERFACE_NAME = "PageFlip";
	@Override
	public String getInterfaceName() {
		return mBrowser.application.resources.prefix + INTERFACE_NAME;
	}
	@Override
	public JavascriptInterface getInheritInterface(Browser childBrowser) {
		return this;
	}
	@Override
	public JavascriptInterface getNewInterface(Browser childBrowser) {
		return new RexseePageFlip(childBrowser);
	}

	public static final String EVENT_ONFLIPDIALOGDISMISSED = "onFlipDialogDismissed";

	private final Context mContext;
	private final Browser mBrowser;
	private final HashMap<String, PageFlipDialog> mMap;

	public void destroyAll() {
		if (mMap.size() == 0) return;
		Collection<PageFlipDialog> collection = mMap.values();
		if (collection == null) return;
		Iterator<PageFlipDialog> iterator = collection.iterator();
		while (iterator.hasNext()) {
			PageFlipDialog w = iterator.next();
			if (w != null) w.pageView.destroy();
		}
	}

	public RexseePageFlip(Browser browser) {
		super();
		mBrowser = browser;
		mContext = browser.getContext();
		mMap = new HashMap<String, PageFlipDialog>();
		mBrowser.eventList.add(EVENT_ONFLIPDIALOGDISMISSED);
	}

	//JavaScript Interface

	public void show(String url, String style) {
		show(null, url, style, 0, null);
	}
	public void show(String id, String url, String style, int startIndex, String pregFilter) {
		final String dialogId = (id != null) ? id : url;
		if (mMap.containsKey(dialogId)) {
			mBrowser.exception(getInterfaceName(), "Duplicated dialog id.");
			return;
		}
		String source = mBrowser.urlListeners.getContent(mBrowser.urlListeners.getAbsoluteUrl(url));
		if (source == null || source.startsWith(RexseeApplication.EXCEPTION_PREFIX)) {
			mBrowser.exception(getInterfaceName(), source);
			return;
		}
		if (pregFilter != null && !pregFilter.trim().equals("")) {
			PregFilterListener listener = (PregFilterListener) mBrowser.urlListeners.getFilter(RexseePregFilter.PREG_FILTER_TYPE, pregFilter);
			if (listener != null) {
				for (int i = 0; i < listener.pregPairs.size(); i++) {
					PregPair pair = listener.pregPairs.get(i);
					source = source.replaceAll(pair.source, pair.replacement);
				}
			}
		}
		showData(dialogId, source, style, startIndex);
	}
	public void showData(final String id, final String data, final String style, final int startIndex) {
		if (id == null || id.equals("") || data == null || data.equals("")) {
			mBrowser.exception(getInterfaceName(), "Invalid arguments.");
			return;
		}
		if (mMap.containsKey(id)) {
			mBrowser.exception(getInterfaceName(), "Duplicated dialog id.");
			return;
		}

		((Activity) mContext).runOnUiThread(new Runnable() {
			@Override
			public void run() {
				try {
					final PageFlipDialog flipDialog = new PageFlipDialog(mBrowser, id, style);
					flipDialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
						@Override
						public void onDismiss(DialogInterface dialog) {
							flipDialog.pageView.destroy();
							flipDialog.pageView = null;
							mMap.remove(id);
							mBrowser.eventList.run(EVENT_ONFLIPDIALOGDISMISSED, new String[]{id});
						}
					});
					flipDialog.start();
					mMap.put(id, flipDialog);
					flipDialog.pageView.load(data, startIndex);
				} catch (Exception e) {
					mBrowser.exception(getInterfaceName(), e);
				}
			}
		});

	}

	public void loadData(String id, final String data, final int startIndex) {
		if (!mMap.containsKey(id)) return;
		final PageFlipDialog dialog = mMap.get(id);
		((Activity) mContext).runOnUiThread(new Runnable() {
			@Override
			public void run() {
				try {
					dialog.pageView.load(data, startIndex);
				} catch (Exception e) {
					mBrowser.exception(getInterfaceName(), e);
				}
			}
		});
	}

	public void dismiss(String id) {
		if (!mMap.containsKey(id)) return;
		PageFlipDialog dialog = mMap.get(id);
		try {
			if (dialog != null) dialog.dismiss();
			mMap.remove(id);
		} catch (Exception e) {
		}
	}
	public void dismissAll() {
		if (mMap.size() == 0) return;
		Set<String> keys = mMap.keySet();
		Iterator<String> iterator = keys.iterator();
		while (iterator.hasNext()) {
			String key = iterator.next();
			PageFlipDialog dialog = mMap.get(key);
			if (dialog != null) {
				try {
					dialog.dismiss();
				} catch (Exception e) {
				}
			}
		}
		try {
			mMap.clear();
		} catch (Exception e) {
		}
	}
	public void setStyle(String id, String style) {
		if (id == null || id.trim().equalsIgnoreCase("") || !mMap.containsKey(id)) {
			mBrowser.exception(getInterfaceName(), "The dialog specified by the id does not exist.");
			return;
		}
		mMap.get(id).setStyle(style);
	}
	public String getStyle(String id, String name) {
		return (!mMap.containsKey(id)) ? "" : mMap.get(id).getStyle(name);
	}
	public boolean exists(String id) {
		return mMap.containsKey(id);
	}
	public int size() {
		return mMap.size();
	}
	public String getIds() {
		String rtn = "";
		Set<String> ids = mMap.keySet();
		Iterator<String> iterator = ids.iterator();
		while (iterator.hasNext()) {
			if (!rtn.equals("")) rtn += ",";
			rtn += "\"" + iterator.next() + "\"";
		}
		return "[" + rtn + "]";
	}

	public int getPageTotal(String id) {
		if (!mMap.containsKey(id)) {
			mBrowser.exception(getInterfaceName(), "Invalid page dialog ID.");
			return -1;
		}
		return mMap.get(id).pageView.getPageTotal();
	}
	public String getPageIndexes(String id) {
		if (!mMap.containsKey(id)) {
			mBrowser.exception(getInterfaceName(), "Invalid page dialog ID.");
			return "[]";
		}
		return mMap.get(id).pageView.getPageIndexes();
	}
	public int getPageIndex(String id) {
		if (!mMap.containsKey(id)) {
			mBrowser.exception(getInterfaceName(), "Invalid page dialog ID.");
			return -1;
		}
		return mMap.get(id).pageView.getPageIndex();
	}
	public void setPageIndex(String id, int index) {
		if (!mMap.containsKey(id)) {
			mBrowser.exception(getInterfaceName(), "Invalid page dialog ID.");
			return;
		}
		mMap.get(id).pageView.setPageIndex(index);
	}
	public String getPageTitle(String id) {
		if (!mMap.containsKey(id)) {
			mBrowser.exception(getInterfaceName(), "Invalid page dialog ID.");
			return "";
		}
		return mMap.get(id).pageView.getPageTitle();
	}
	public String getPageTitle(String id, int index) {
		if (!mMap.containsKey(id)) {
			mBrowser.exception(getInterfaceName(), "Invalid page dialog ID.");
			return "";
		}
		return mMap.get(id).pageView.getPageTitle(index);
	}
	public String searchText(String id, String text) {
		if (!mMap.containsKey(id)) {
			mBrowser.exception(getInterfaceName(), "Invalid page dialog ID.");
			return "[]";
		}
		return (text.trim().equals("")) ? mMap.get(id).pageView.getPageIndexes() : mMap.get(id).pageView.searchText(text);
	}

}
